import axios from 'axios';
import { Message } from 'element-ui';
import store from '../store';
import router from '../router';
import Cookies from 'js-cookie';
import moment from 'moment';
import md5 from 'md5';

// 创建axios实例
const service = axios.create({
    baseURL: process.env.BASE_API, // api的base_url
    timeout: 20000 // 请求超时时间
});

// request拦截器
service.interceptors.request.use(config => {
    // Do something before request is sent
    function getRandom(n,m){
        n = Number(n);    //强制转换成数字
        m = Number(m);
        if (isNaN(n)||isNaN(m)) {    //判断是否为有效数字 ，其中一个不是有效数字就返回[0,1)之间的随机小数
            return math.random();
        }
        if (n > m) {     //如果n>m则交换
            let temp=n;
            n=m;
            m=temp;
        }
        return Math.round(Math.random()*(m-n)+n);
    }
    function getSixNo(){
        let arr=[];
        for (let i=0;i<6;i++){
            arr.push(getRandom(0,9));
        }
        return arr.join('');
    }

    const servCode = 'exueyunServ'
    const randNum = getSixNo(); //6位随机码
    const realTime = moment().format('YYYYMMDDHHmmss'); //流水号前面的时间 格式：yyyyMMddHHmmss
    const sendTime = moment().format('YYYY-MM-DD HH:mm:ss'); //消息发送时间，必填，格式为：yyyy-MM-dd HH:mm:ss
    let transId = realTime + randNum; //唯一消息流水号，必填，格式为：yyyyMMddHHmmss+6位随机码 隐藏规则:对于同一客户端类型且同一ip的同一个用户, 如果请求一直是一样的yyyyMMddHHmmss, 则认为是不合法的请求 
    /**
     * 例如:
     * SERVCODE: exueyunServ
     * TRANSID: 20180517125812ui234h
     * 则以"exueyunServ20180517125812ui234h"生成MD5码
     */ 
    let sysSign = servCode + transId;
    sysSign = md5(sysSign);
    /**
     * 请求的消息头(header)添加SENDER,RECEIVER,TIME,SERVCODE,MSGTYPE,TRANSID,VERSION,SYSSIGN
     * by cuihd 2018-05-22
     */
    config.headers['SENDER'] = 'exueyun'; //消息发送方，必填，为：exueyun
    config.headers['RECEIVER'] = servCode; //消息接收方，必填，为：exueyunServ
    config.headers['TIME'] = sendTime; //消息发送时间，必填，格式为：yyyy-MM-dd HH:mm:ss
    config.headers['SERVCODE'] = servCode; //服务编码，必填. 为：exueyunServ        
    config.headers['MSGTYPE'] = 'request'; //消息类型，必填, 为：request      
    config.headers['TRANSID'] = transId; //唯一消息流水号，必填，格式为：yyyyMMddHHmmss+6位随机码 隐藏规则:对于同一客户端类型且同一ip的同一个用户, 如果请求一直是一样的yyyyMMddHHmmss, 则认为是不合法的请求    
    config.headers['VERSION'] = '2.0'; //协议版本号，默认:2.0
    config.headers['SYSSIGN'] = sysSign; //鉴权，32字节的MD5字符串。生成方式：32位的MD5（ServCode+ TransId）注：将消息头中的服务编码和消息流水号拼接后用MD5加密。

    config.headers['clientType'] = '1:1'; //为了统计在线用户的信息，客户端类型:登录用户的身份类型
    config.headers['Content-Type'] = 'application/json;charset=UTF-8';
    // store.getters.token
    if (store.getters.token) {
        // config.headers['uid'] = store.getters.uid;
        config.headers['accessToken'] = store.getters.token; // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
    }
    const crypto = require('crypto');
    /**
     * @author cuihd
     * created by cuihd at 2018-07-10
     * aes加密方法
     * @param key   加密key
     * @param iv    向量(偏移量),ecb模式下可以不要
     * @param data  需要加密的数据
     * @returns string
     */
    let encrypt = function (key, iv, data) {
        let cipher = crypto.createCipheriv('aes-128-ecb', key, iv); 
        let crypted = cipher.update(data, 'utf8', 'binary');
        crypted += cipher.final('binary');
        crypted = new Buffer(crypted, 'binary').toString('base64');// 由二进制数转为base64
        return crypted;
    };
    /**
     * @author cuihd
     * created by cuihd at 2018-07-10
     * aes解密方法
     * @param key      解密的key
     * @param iv       向量
     * @param crypted  密文
     * @returns string
     */
    let decrypt = function (key, iv, crypted) {
        crypted = new Buffer(crypted, 'base64').toString('binary');// 先讲base64转为二进制
        let decipher = crypto.createDecipheriv('aes-128-ecb', key, iv);
        let decoded = decipher.update(crypted, 'binary', 'utf8');
        decoded += decipher.final('utf8');
        return decoded;
    };
    /**
     * @author cuihd
     * creatd by cuihd at 2018-07-20
     * 需要加密api的配置
     * 
     */
    const apiList = [ //加密api配置
        'http://api.agent.jzexueyun.com/agent/', // 正式服
        // 'http://press.agent.juziwl.cn:8090/agent/', // 压测服
        'http://it.agent.juziwl.cn:8090/agent/', // 集成测试服
        // 'http://test.agent.juziwl.cn:8091/agent/' // 测试服
    ]
    if (config.data && apiList.some(item => process.env.BASE_API == item)){ 
        let newKey = String(transId).substring(4),        
        newData = JSON.stringify(config.data);
        config.data = encrypt(newKey, '', newData);    
    }
    return config;
}, error => {
    // Do something with request error
    console.log(error); // for debug
    Promise.reject(error);
})

// respone拦截器
service.interceptors.response.use(
    response => {
        /**
         * 下面的注释为通过response自定义code来标示请求状态，当code返回如下情况为权限有问题，登出并返回到登录页
         * 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中
         */
        const res = response.data;
        if (res.status !== 200) {
            let msg = '参数错误！';
            switch (res.status) {
                case 1100:
                    msg = '过于频繁，请稍后再试！';
                    break;
                case -1:
                    msg = res.errorMsg;
                    break;
                case 4001:
                    msg = '访问过期，重新跳转到登录页面！';
                    setTimeout(() => {
                        store.dispatch('FedLogOut').then(() => {
                            location.reload(); // 为了重新实例化vue-router对象 避免bug
                        });
                    }, 3000);
                    break;
                case 4002:
                    msg = '不合法的凭证！';
                    break; //token失效规则是，2小时不请求，就失效
                case 4004:
                    msg = '页面不存在！';
                    break;
                case 4005:
                    msg = '没有权限访问该页面！';
                    break;
                case 4011:
                    msg = '';
                    break;
                case 5050:
                    // 返回5050 维护
                    router.replace({
                        path: 'error',
                    });
                    Cookies.set('startTime', res.content.startTime);
                    Cookies.set('endTime', res.content.endTime);
                    Cookies.set('path', res.content.path);
                    msg = '';
                    break;
                case 4018:
                    msg = '';
                    break;
                default:
                    msg = res.errorMsg;
            };
            if (msg) {
                if (msg.length > 100) {
                    msg='网络错误，请稍后再试。';
                } 
                Message({
                    message: msg,
                    type: 'error',
                    duration: 5 * 1000
                });
            }
            // return Promise.reject(error);
            return Promise.reject(res.errorMsg);
        } else {
            // return response;
            return Promise.resolve(response);
        }
    },
    error => {
        // console.log('err' + error); // for debug ECONNABORTED
        let ErrorMsg = error.message;
        if (error.code=='ECONNABORTED') ErrorMsg = '请求超时，请稍后再试。';
        Message({
            message: ErrorMsg,
            type: 'error',
            duration: 5 * 1000
        });
        return Promise.reject(error);
    }
)

export default service;